function init (varargin)

   ## usage: init (varargin)
   ## 
   ## initialize variables and create directories

   persistent CFG INIT = false

   if !INIT
      f = dbstack ; printf("\n\t###   %s   ###\n\n", f(1).name) ;
   endif

   pkg unload all ; clear -g AVAR SVAR GVAR
   global lim=-999 verbose=0 RND GVAR isANA isCUR ADIR SDIR CDIR
   global PAR PRJ PRSV NCPU = nproc BATCH ;

   for i = 1:nargin
      eval(varargin{i}) ;
   endfor

   ## system related \\
   if !isunix
      error("init: No unix system. Exiting.\n") ;
   endif
   if isempty(BATCH), BATCH = isempty(strfind(program_invocation_name, "octave")) ; endif
   PAR.HAS64 = (isfield(octave_config_info, "USE_64_BIT_IDX_T") && octave_config_info.USE_64_BIT_IDX_T) ;
   ## [status PAR.mem] = system("cat /proc/meminfo | head -1 | awk '{print $2}'") ;
   ## PAR.mem = str2num(strtrim(PAR.mem)) * 1e3 / sizeof(0) ;
   [~, PAR.mem] = computer ; PAR.mem /= 10 ;
   if !exist(rfile = "rand_init.ob", "file")
      v = rand("state") ;
      save(rfile, "v") ;
   else
      load(rfile) ;
      rand("state", v) ;
   endif 
   warning("off", "Octave:assign-as-truth-value") ;
   warning("off", "Octave:shadowed-function") ;
   warning("off", "Octave:broadcast") ;
   warning("off", "backtrace") ;
   ## system related //

   ### defaults \\
   source("xds.cfg") ;
   if exist("PDD", "var"), PAR.pdd = PDD ; endif
   if exist("RES", "var"), PAR.res = RES ; endif
   if exist("ANA", "var"), PAR.ana = ANA ; endif 
   if ischar(CFG) && exist(CFG, "file"), source(CFG) ; endif
   if exist("SIM", "var") && !isempty(SIM)
      PAR.sim = strsplit(SIM, " ") ;
   endif
   if exist(file = fullfile("data", PAR.ana, "res.cfg"), "file") ; source(file) ; endif
   if exist(file = [PAR.res ".cfg"], "file") ; source(file) ; endif
   ### defaults //

   if !INIT && exist("BLD", "var"), bld(BLD) ; endif

   if !exist("TOP", "var")
      TOP = fullfile(pwd, "data") ;
   endif 
   pmkdir(TOP) ;
   if !isfield(PAR, "sim") || (exist("SIM", "var") && isempty(SIM))
      printf("init: no simulations defined, using %s.\n", PAR.ana) ;
      PAR.sim = {PAR.ana, PAR.ana} ;
      SVAR = AVAR ;
   endif 
   if length(PAR.sim) == 1
      PAR.sim = [PAR.sim PAR.sim] ;
   endif
   MDL = strsplit(PAR.sim{1}, "/"){1} ;
   if exist(file = [MDL ".cfg"], "file") ; source(file) ; endif
   if !exist("SVAR", "var")
      SVAR = AVAR ;
   endif 

   Gpfx = "" ;

   gdata = fullfile("data", PRJ, PAR.ptr) ;
   ldata = fullfile("data", PRJ, PAR.pdd) ;

   if PAR.udf
      MODSFX = [MODSFX "_udf"] ; eofdir = "eof_udf" ;
   else
      eofdir = "eof" ;
   endif

   ANASFX = PAR.res ; # ugly hack for resolution settings
   wANA = strrep(PAR.ana, "/", "_") ;

   PAR.mfile = fullfile(ldata, [ANASFX MODSFX], [wANA ".mod.ob"]) ;
   PAR.plist = fullfile(ldata, [ANASFX MODSFX], [wANA ".ptr.lst"]) ;

   wRES = strrep(PAR.res, ".", "") ;
   isANA = @strcmp(PAR.sim{1}, PAR.ana) ;
   isCUR = @strcmp(PAR.sim{:}) ;
   if isANA
      PAR.ptradj = "" ;
      SVAR = AVAR ;
   else
      PAR.res = "" ; # at this point, GCM resolution is a given
      pmkdir(fullfile(gdata, PAR.sim{2}, PAR.res, "clim")) ;
   endif 

   ADIR = fullfile(gdata, PAR.ana, ANASFX) ;
   SDIR = fullfile(gdata, PAR.sim{1}, PAR.res) ;
   CDIR = fullfile(gdata, PAR.sim{2}, PAR.res) ;

   pmkdir(fullfile(ldata, [ANASFX MODSFX]), fullfile(ADIR, PAR.pdd)) ;
   pmkdir(fullfile(ADIR, "clim"), fullfile(ADIR, eofdir)) ;
   pmkdir(ldata, fullfile(SDIR, PAR.pdd)) ;

   if isempty(GVAR), GVAR = [AVAR; SVAR] ; endif

   if isfield(PAR, "ncpu")
      PAR.ncpu = min(NCPU, PAR.ncpu) ;
   else
      PAR.ncpu = NCPU/2 ;
   endif 

   if !INIT
      printf("init: PRJ = %s\n", PRJ) ;
      printf("init: PTR = %s\n", PAR.ptr) ;
      printf("init: PDD = %s\n", PAR.pdd) ;
      printf("init: MDL = %s\n", MDL) ;
      printf("init: ANA = %s\n", PAR.ana) ;
      printf("init: SIM = %s %s\n", PAR.sim{:}) ;
      printf("init: RES = %s\n", wRES) ;
      INIT = true ;
   endif
   dp_upd(PAR) ;

   if isANA
      f = [fileparts(PAR.mfile) "/PAR.txt"] ;
      fprintf(fid = fopen(f, "wt"), "%s", disp(PAR)) ; fclose(fid) ;
   endif

endfunction
